package com.aote.rs;

import java.math.BigDecimal;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.Context;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.springframework.web.context.ContextLoaderListener;

import com.aote.rs.entity.WxConfig;
import com.aote.rs.entity.WxPayReturnData;
import com.aote.rs.entity.WxPaySendData;
import com.aote.rs.util.WxSign;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;

/**
 * 预付费处理
 */
public class WxPrepay {

	static Logger log = Logger.getLogger(WxPrepay.class);

	public JSONObject prePay(HttpServletRequest request,
			HttpServletResponse response) {
		JSONObject result = new JSONObject();
		try {
			WxConfig wxConfig = (WxConfig) ContextLoaderListener
					.getCurrentWebApplicationContext().getBean("wxConfig");
			String id = request.getSession().getId();
			String appId = wxConfig.getAppID();
			String key = wxConfig.getKey();
			String openid = request.getParameter("openid");
			String money = request.getParameter("money");
			log.debug("weixin-start-getprepayid" + ",sessionid=" + id
					+ ",openid=" + openid + ",money=" + money);
			WxPaySendData sendData = getPaySendEntity(wxConfig, money, openid,
					request);
			log.debug("sendData=" + sendData);
			// 下单处理,返回数据为xml
			String returnXml = unifiedOrder(sendData, wxConfig);
			log.debug("returnXml=" + returnXml);
			WxPayReturnData reData = new WxPayReturnData();
			XStream xs1 = new XStream(new DomDriver());
			xs1.alias("xml", WxPayReturnData.class);
			reData = (WxPayReturnData) xs1.fromXML(returnXml);
			// 判断返回数据
			String return_code = reData.getReturn_code();
			if (return_code.equals("SUCCESS")) {
				if (reData.getResult_code().equals("SUCCESS")) {

				} else {
					result.put(
							"error",
							"返回错误：" + reData.getErr_code()
									+ reData.getErr_code_des());
				}
			} else {
				result.put("error", "系统错误：" + reData.getReturn_msg());
			}
			/*if (return_code.equals("SUCCESS")) {
				result.put("error", "系统错误：" + reData.getReturn_msg());
				log.debug("result=" + result);
				return result;
			}*/
			// 跳转支付页面
			SortedMap<Object, Object> finalpackage = new TreeMap<Object, Object>();
			String timestamp = WxSign.getTimeStamp();
			String nonceStr2 = WxSign.getNonceStr();
			String prepay_id2 = "prepay_id=" + reData.getPrepay_id();
			String packages = prepay_id2;
			finalpackage.put("appId", appId);
			finalpackage.put("timeStamp", timestamp);
			finalpackage.put("nonceStr", nonceStr2);
			finalpackage.put("package", packages);
			finalpackage.put("signType", "MD5");
			String finalsign = WxSign.createSign(finalpackage, key);
			result.put("appId", appId);
			result.put("timeStamp", timestamp);
			result.put("nonceStr", nonceStr2);
			result.put("pg", prepay_id2);
			result.put("sign", finalsign);
			result.put("signType", "MD5");
			
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		log.debug("result=" + result);
		return result;
	}

	public WxPaySendData getPaySendEntity(WxConfig config, String money,
			String openid, HttpServletRequest request) {
		WxPaySendData result = new WxPaySendData();
		result.setAppid(config.getAppID());// appid
		result.setAttach("微信支付");
		result.setBody("微信公众号支付");
		result.setMch_id(config.getMchID()); //商户id
		result.setNonce_str(WxSign.getNonceStr());
		result.setNotify_url(config.NOTIFY_URL);//支付完回调地址
		result.setOut_trade_no(WxSign.getNonceStr()); // 随机数
		BigDecimal v1 = new BigDecimal(money);
        BigDecimal v2 = new BigDecimal("100");
        Double b = v1.multiply(v2).doubleValue();
        int fee1 = b.intValue();
        result.setTotal_fee(fee1);
		//result.setTotal_fee((int) (Double.parseDouble(money) * 100));// 单位：分 支付金额
		// setTrade_type 交易类型 JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付
		result.setTrade_type("JSAPI");
		result.setSpbill_create_ip(request.getRemoteAddr()); //订单生成的机器IP，指用户浏览器端IP  
		result.setOpenid(openid);
		return result;
	}

	public static String unifiedOrder(WxPaySendData data, WxConfig config) {
		// 统一下单支付
		String returnXml = null;
		try {
			// 生成sign签名
			SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
			parameters.put("appid", data.getAppid());
			parameters.put("attach", data.getAttach());
			parameters.put("body", data.getBody());
			parameters.put("mch_id", data.getMch_id());
			parameters.put("nonce_str", data.getNonce_str());
			parameters.put("notify_url", data.getNotify_url());
			parameters.put("out_trade_no", data.getOut_trade_no());
			parameters.put("total_fee", (Integer) data.getTotal_fee());
			parameters.put("trade_type", data.getTrade_type());
			parameters.put("spbill_create_ip", data.getSpbill_create_ip());
			parameters.put("openid", data.getOpenid());
			parameters.put("device_info", data.getDevice_info());
			data.setSign(WxSign.createSign(parameters, config.getKey()));
			XStream xs = new XStream(new DomDriver("UTF-8",
					new XmlFriendlyNameCoder("-_", "_")));
			xs.alias("xml", WxPaySendData.class);
			String xml = xs.toXML(data);
			DefaultHttpClient httpclient = new DefaultHttpClient();
			HttpPost postRequest = new HttpPost(config.DOWN_PAY_API);
			StringEntity postEntity = new StringEntity(xml, "UTF-8");
			postRequest.addHeader("Content-Type", "text/xml");
			postRequest.setEntity(postEntity);
			HttpResponse httpResponse = httpclient.execute(postRequest);
			HttpEntity entity = httpResponse.getEntity();
			if (entity != null) {
				returnXml = EntityUtils.toString(entity, "UTF-8");
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return returnXml;
	}

}
